#include "my_buzzer.h"
#include "my_gpio.h"



static TIM_TimeBaseInitType TIM_TimeBaseStructure;
static OCInitType TIM_OCInitStructure;
static uint16_t PrescalerValue = 0;


static void buzzer_gpio_cfg(void);

typedef struct{

    int on_time;
    int off_time;
    int off_cnt;
    int repeat_time;
}BUZZER_PARAM_t;

static BUZZER_PARAM_t buzzer_data = {0};


/*******
 * 为无源蜂鸣器，暂时用40khz左右的高低电平驱动
 * PB9------BUZZ_PWM       // 蜂鸣器 4khz（TIMER4-CH4 ----AF2）
 *          关闭时为输出低电平
 * 
 * 
 *  10ms任务调用一次， 长鸣 400ms， 短鸣 200ms
 * ***/
void buzzer_on(void)
{
#if(BUZZ_MODE_SEL == BUZZ_USE_TIMER)    
    buzzer_gpio_cfg();
    TIM_ConfigOc4Preload(TIM4, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM4, ENABLE);
    sys_data.beep_on_flag = 1;
    #ifdef DEBUG_OPEN_PRINT    
        printf("buzzer_on \r\n");
    #endif
#else
    set_pin_tirrgle(BUZZER_PORT, BUZZER_PIN);
    //   printf("buzzer_on \r\n");
    // set_pin_high(BUZZER_PORT, BUZZER_PIN);
#endif
}

void buzzer_only_close(void)
{
#if(BUZZ_MODE_SEL == BUZZ_USE_TIMER)
    TIM_Enable(TIM4, DISABLE);
	gpio_output_cfg(BUZZER_PORT, BUZZER_PIN);
	set_pin_low(BUZZER_PORT, BUZZER_PIN);
    sys_data.beep_on_flag = 0;
    #ifdef DEBUG_OPEN_PRINT    
        printf("buzzer_only_close \r\n");
    #endif
#else
    printf("buzzer_off_only \r\n");
    set_pin_low(BUZZER_PORT, BUZZER_PIN);
#endif

}

void buzzer_off(void)
{
    if(0 == sys_data.beep_on_flag){
        return;
    }
#if(BUZZ_MODE_SEL == BUZZ_USE_TIMER)
    TIM_Enable(TIM4, DISABLE);
	gpio_output_cfg(BUZZER_PORT, BUZZER_PIN);
	set_pin_low(BUZZER_PORT, BUZZER_PIN);
   
#ifdef DEBUG_OPEN_PRINT     
    printf("buzzer_off2 \r\n");
#endif 
#else
    printf("buzzer_off \r\n");
    set_pin_low(BUZZER_PORT, BUZZER_PIN);
#endif    
    sys_data.beep_on_flag = 0;
}

int get_buzzer_repeat_time(void)
{
    return buzzer_data.repeat_time;
}

/**********************
 * 每10ms调用一次
 * 
 * 
*/
void buzzer_state_ctrl(void)
{
    if(sys_data.beep_on_cnt){
        sys_data.beep_on_cnt --;
    }

    if(buzzer_data.repeat_time > 1){
        if(0 == sys_data.beep_on_cnt){

            if(buzzer_data.off_cnt){
                buzzer_data.off_cnt --;
                buzzer_only_close();
            }
            else{
                buzzer_data.repeat_time --;
                buzzer_data.off_cnt = buzzer_data.off_time;
                sys_data.beep_on_cnt = buzzer_data.on_time;
                buzzer_on();
                sys_data.beep_finish_flag = 0;
                //   printf("repeat_tmie:[%d] 22222\r\n", buzzer_data.repeat_time);
            }
        }   
    } // 重复结束，计时倒了之后，关闭蜂鸣器
    else{

        if(0 == sys_data.beep_on_cnt){
            buzzer_off();
            if(1 == buzzer_data.repeat_time){
                sys_data.beep_finish_flag = 1;
								buzzer_data.repeat_time = 0;
                // printf("sys_data.beep_finish_flag == 1 \r\n");
                // buzzer_only_close();
            }
        //  printf("repeat_tmie:[%d] \r\n", buzzer_data.repeat_time);
        }
    } 
}

void buzzer_shor_on(void)
{
    sys_data.beep_on_flag = 1;
    sys_data.beep_on_cnt = 6;
    sys_data.beep_finish_flag = 0;
	buzzer_on();
    // printf("buzzer_shor_on  \r\n");
}

/*************
 *  蜂鸣器被10ms执行一次，所以参数也是10ms参数
 * **/
void buzzer_on_with_param(int on_time, int off_time, int repeat_time)
{
    buzzer_data.on_time = on_time;
    buzzer_data.off_time = off_time;
    buzzer_data.off_cnt = off_time;
    buzzer_data.repeat_time = repeat_time;

    sys_data.beep_on_flag = 1;
    sys_data.beep_on_cnt = buzzer_data.on_time;
    sys_data.beep_finish_flag = 0;
	buzzer_on();
    // printf("buzzer_on_with_param :repeat_time[%d]  \r\n", buzzer_data.repeat_time);
}


void buzzer_long_on(void)
{
    sys_data.beep_on_flag = 1;
    sys_data.beep_on_cnt = 11;
	buzzer_on();
#ifdef DEBUG_OPEN_PRINT     
    printf("buzzer_shor_on  \r\n");
#endif    
}

static void buzzer_rcc_cfg(void)
{
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM4, ENABLE);
}

static void buzzer_gpio_cfg(void)
{
   GPIO_InitType GPIO_InitStructure;

    GPIO_InitStruct(&GPIO_InitStructure);
#if(BUZZ_MODE_SEL == BUZZ_USE_TIMER)    
    /* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */
    // Pb9----[TIM4_CH4 ---AF2]
    GPIO_InitStructure.Pin        = BUZZER_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_TIM4;
    GPIO_InitPeripheral(BUZZER_PORT, &GPIO_InitStructure);
#else
    gpio_output_cfg(BUZZER_PORT, BUZZER_PIN);
#endif    
}

static void buzzer_freq_select_4khz(void)
{
    TIM_Enable(TIM4, DISABLE);

  /* Compute the prescaler value */
    PrescalerValue = 64 -1 ; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = 1000/4;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 4 ch4    
    TIM_InitTimeBase(TIM4, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period/2; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc4(TIM4, &TIM_OCInitStructure);
    TIM_ConfigOc4Preload(TIM4, TIM_OC_PRE_LOAD_ENABLE);
    // TIM_Enable(TIM4, ENABLE);
    //---------------timer 5 ch2
}

void my_buzzer_init(void)
{
    buzzer_gpio_cfg();
#if(BUZZ_MODE_SEL == BUZZ_USE_TIMER)    
    buzzer_rcc_cfg();
    buzzer_freq_select_4khz();
#endif
}
